﻿using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using SpriteAnimator.Classes;

namespace SpriteAnimator
{
    /// <summary>
    /// Form principale de l'application
    /// </summary>
    public partial class frmMain: Form
    {
        #region Variables statiques

        public static int SPRITE_INDEX = 1;
        public static int TEXTURE_INDEX = 1;

        #endregion

        #region Constructeurs

        /// <summary>
        /// Constructeur de la form
        /// </summary>
        public frmMain()
        {
            this.InitializeComponent();
        }

        #endregion

        #region Evénements de l'application

        /// <summary>
        /// Click pour créer un nouveau sprite
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuFichierNouveau_Click(object sender, EventArgs e)
        {
            try
            {
                using ( frmItemChoice oInput = new frmItemChoice() )
                {
                    // *** On fait la demande ***

                    if ( oInput.ShowDialog(this) == DialogResult.OK )
                    {
                        if ( oInput.ProjectType == ProjectType.Texture )
                        {
                            frmMain.TEXTURE_INDEX++;
                            this.CreerTextureMDI(oInput.ProjectName, string.Empty);
                        }
                        else
                        {
                            frmMain.SPRITE_INDEX++;
                            this.CreerSrpiteMDI(oInput.ProjectName, string.Empty);
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                frmMain.ShowError(ex);
            }
        }

        /// <summary>
        /// Click pour accéder aux options
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuFichierOption_Click(object sender, EventArgs e)
        {
            using ( frmOptions oOption = new frmOptions() )
            {
                oOption.ShowDialog(this);
            }
        }

        /// <summary>
        /// Click pour fermer l'application
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuFichierQuitter_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Click pour ouvrir un fichier
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuFichierOuvrir_Click(object sender, EventArgs e)
        {
            try
            {
                // *** Ouverture de la zone de saisie ***

                if ( this.dlgOpen.ShowDialog(this) == DialogResult.OK )
                {
                    string sTexture = Path.GetDirectoryName(this.dlgOpen.FileName) + Path.GetFileNameWithoutExtension(this.dlgOpen.FileName) + ".png";

                    // *** Vérification présence texture ***

                    if ( !File.Exists(sTexture) )
                        MessageBox.Show(this, "Impossible de trouver la texture associée au fichier sprite.\n\n" + sTexture, "Chargement impossible", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    else
                    {
                        if ( Path.GetExtension(this.dlgOpen.FileName).Equals(".n2t") )
                            this.CreerTextureMDI(Path.GetFileNameWithoutExtension(this.dlgOpen.FileName), this.dlgOpen.FileName);
                        else
                            this.CreerSrpiteMDI(Path.GetFileNameWithoutExtension(this.dlgOpen.FileName), this.dlgOpen.FileName);
                    }
                }
            }
            catch ( Exception ex )
            {
                frmMain.ShowError(ex);
            }
        }

        /// <summary>
        /// Click pour enregistrer
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuFichierEnregistrer_Click(object sender, EventArgs e)
        {
            if ( this.ActiveMdiChild != null )
                (this.ActiveMdiChild as frmSprite).Save(false);
        }

        /// <summary>
        /// Click pour enregistrer sous un autre nom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuFichierEnregistrerSous_Click(object sender, EventArgs e)
        {
            if ( this.ActiveMdiChild != null )
            {
                if ( this.ActiveMdiChild is frmZoneTexture )
                    (this.ActiveMdiChild as frmZoneTexture).Save(true);
                else
                    (this.ActiveMdiChild as frmSprite).Save(true);
            }
        }

        /// <summary>
        /// Click pour le menu a propos
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuHelpPropos_Click(object sender, EventArgs e)
        {
            using ( frmAbout oAbout = new frmAbout() )
            {
                oAbout.ShowDialog(this);
            }
        }

        /// <summary>
        /// Click boucle
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuBoucleOn_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetLoop(true);
            }
        }

        /// <summary>
        /// Click boucle
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuBoucleOff_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetLoop(false);
            }
        }

        /// <summary>
        /// Click zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom100_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetZoom(ZoomMode.Zoom100);
            }
        }

        /// <summary>
        /// Click zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom125_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetZoom(ZoomMode.Zoom125);
            }
        }

        /// <summary>
        /// Click zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom150_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetZoom(ZoomMode.Zoom150);
            }
        }

        /// <summary>
        /// Click zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom175_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetZoom(ZoomMode.Zoom175);
            }
        }

        /// <summary>
        /// Click zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom200_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetZoom(ZoomMode.Zoom200);
            }
        }

        /// <summary>
        /// Click zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom250_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetZoom(ZoomMode.Zoom250);
            }
        }

        /// <summary>
        /// Click zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom300_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetZoom(ZoomMode.Zoom300);
            }
        }

        /// <summary>
        /// Click color
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuColorInit_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetBackground(Color.CornflowerBlue);
            }
        }

        /// <summary>
        /// Click color
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuColorChange_Click(object sender, EventArgs e)
        {
            this.dlgColor.Color = Color.CornflowerBlue;

            if ( this.dlgColor.ShowDialog(this) == DialogResult.OK )
            {
                foreach ( Form oForm in this.MdiChildren )
                {
                    if ( oForm is frmSprite )
                        (oForm as frmSprite).SetBackground(this.dlgColor.Color);
                }
            }
        }

        /// <summary>
        /// Pour ouvrir la fenêtre de texture
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuSpriteTexture_Click(object sender, EventArgs e)
        {
            if ( this.ActiveMdiChild != null && this.ActiveMdiChild is frmSprite )
                (this.ActiveMdiChild as frmSprite).ShowTexture();
        }

        /// <summary>
        /// Pour ouvrir la fenêtre de frame
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuSpriteFrames_Click(object sender, EventArgs e)
        {
            if ( this.ActiveMdiChild != null && this.ActiveMdiChild is frmSprite )
                (this.ActiveMdiChild as frmSprite).ShowFrames();
        }

        /// <summary>
        /// Pour ouvrir la fenêtre d'animation
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuSpriteAnimations_Click(object sender, EventArgs e)
        {
            if ( this.ActiveMdiChild != null && this.ActiveMdiChild is frmSprite )
                (this.ActiveMdiChild as frmSprite).ShowAnimation();
        }

        /// <summary>
        /// Click animation
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdBegin_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetAnimationMode(AnimationMode.Begin);
            }
        }

        /// <summary>
        /// Click animation
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdLast_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetAnimationMode(AnimationMode.Previous);
            }
        }

        /// <summary>
        /// Click animation
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdStop_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetAnimationMode(AnimationMode.Stop);
            }
        }

        /// <summary>
        /// Click animation
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdPlay_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetAnimationMode(AnimationMode.Play);
            }
        }

        /// <summary>
        /// Click animation
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdNext_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetAnimationMode(AnimationMode.Next);
            }
        }

        /// <summary>
        /// Click animation
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdEnd_Click(object sender, EventArgs e)
        {
            foreach ( Form oForm in this.MdiChildren )
            {
                if ( oForm is frmSprite )
                    (oForm as frmSprite).SetAnimationMode(AnimationMode.End);
            }
        }

        #endregion

        #region Fonctions privées

        /// <summary>
        /// Ouvre une fenêtre de sprite
        /// </summary>
        /// <param name="p_sTitre">Titre de la fenêtre</param>
        /// <param name="p_sFile">Chemin du fichier de définition si il y a lieu</param>
        private void CreerSrpiteMDI(string p_sTitre, string p_sFile)
        {
            frmSprite oSprite;

            // *** Création de la fenêtre ***

            oSprite = new frmSprite(p_sTitre);
            oSprite.MdiParent = this;

            // *** Chargement du sprite ***

            if ( !string.IsNullOrEmpty(p_sFile) && File.Exists(p_sFile) )
                oSprite.LoadSprite(p_sFile);

            // *** On se bind sur les événements ***

            oSprite.Activated += new EventHandler(this.SpriteActivated);
            oSprite.Deactivate += new EventHandler(this.SpriteDeactivate);

            // *** On l'affiche ***

            oSprite.Show();
        }

        /// <summary>
        /// Ouvre une fenêtre de texture
        /// </summary>
        /// <param name="p_sTitre">Titre de la fenêtre</param>
        /// <param name="p_sFile">Chemin du fichier de définition si il y a lieu</param>
        private void CreerTextureMDI(string p_sTitre, string p_sFile)
        {
            frmZoneTexture oZone;

            // *** Création de la fenêtre ***

            oZone = new frmZoneTexture(p_sTitre);
            oZone.MdiParent = this;

            // *** Chargement du sprite ***

            if ( !string.IsNullOrEmpty(p_sFile) && File.Exists(p_sFile) )
                oZone.LoadTextureZone(p_sFile);

            // *** On se bind sur les événements ***

            oZone.Activated += new EventHandler(this.ZoneActivated);
            oZone.Deactivate += new EventHandler(this.ZoneDeactivate);

            // *** On l'affiche ***

            oZone.Show();
        }

        /// <summary>
        /// Se déclenche sur l'activation d'une fenêtre sprite
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void SpriteActivated(object sender, EventArgs e)
        {
            this.mnuSprite.Visible = true;
            this.mnuFichierEnregistrer.Enabled = true;
            this.mnuFichierEnregistrerSous.Enabled = true;
        }

        /// <summary>
        /// Se déclenche sur l'activation d'une fenêtre sprite
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void SpriteDeactivate(object sender, EventArgs e)
        {
            this.mnuSprite.Visible = false;
            this.mnuFichierEnregistrer.Enabled = false;
            this.mnuFichierEnregistrerSous.Enabled = false;
        }

        /// <summary>
        /// Se déclenche sur l'activation d'une fenêtre zone
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void ZoneActivated(object sender, EventArgs e)
        {
            this.mnuSprite.Visible = true;
            this.mnuFichierEnregistrer.Enabled = true;
            this.mnuFichierEnregistrerSous.Enabled = true;
        }

        /// <summary>
        /// Se déclenche sur l'activation d'une fenêtre zone
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void ZoneDeactivate(object sender, EventArgs e)
        {
            this.mnuSprite.Visible = false;
            this.mnuFichierEnregistrer.Enabled = false;
            this.mnuFichierEnregistrerSous.Enabled = false;
        }

        #endregion

        #region Fonctions statiques

        /// <summary>
        /// Affiche une erreur
        /// </summary>
        /// <param name="e">Détail de l'erreur</param>
        public static void ShowError(Exception e)
        {
            MessageBox.Show("Une erreur est survenue :\n\n" + e.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        #endregion
    }
}
